package cz.pecinovsky.česky.oopnz._134_;
//Příliš žluťoučký kůň úpěl ďábelské ódy
//import static cz.pecinovsky.česky.oopnz._134_.StavitelOkruhů_134_.StavitelOkruhů;

import cz.pecinovsky.česky.oopnz.správce.SprávcePlátna;


import static cz.pecinovsky.česky.oopnz._134_.Okruh_134_        .Okruh;
import static cz.pecinovsky.česky.oopnz._134_.PoleCesty_134_    .PoleCesty;
import static cz.pecinovsky.česky.oopnz._134_.StavStavitele_142_.StavStavitele;
import static cz.pecinovsky.česky.oopnz._134_.StavStavitele_142_.StavStavitele.*;


//import static cz.pecinovsky.česky.oopnz._134_.StavitelOkruhů_134_ .StavitelOkruhů;
////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ Konec ignorovaného počátečního textu +++++
//%I+ 
//
//import cz.pecinovsky.česky.oopnz.správceplátna.SprávcePlátna;
//%I-

import cz.pecinovsky.česky.oopnz.utility.Barva;
import cz.pecinovsky.česky.oopnz.utility.Pozice;
import cz.pecinovsky.česky.oopnz.utility.Směr8;


//%I+ >142
//import static cz.pecinovsky.česky.oopnz.město.StavStavitele.*;
//%I-
//%X+ xxxxx Začátek přeskakovaného textu xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   Není - toto_je_nově_definovaná_třída
 *              Ttt v projektu Ppp
 * Následující: Prozatím není
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class StavitelOkruhů_134_
{    private StavitelOkruhů_134_() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- Konec přeskakovaného textu -----


/*******************************************************************************
 * Instance třídy {@code StavitelOkruhů} představují stavitele,
 * kteří umějí vybudovat okruhy poskládané z instancí třídy {@link PoleCesty}.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class StavitelOkruhů
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Správce plátna, na němž bude okruh zobrazen. */
    SprávcePlátna SP = SprávcePlátna.getInstance();

    /** Implicitní barva cest. */
    private static final Barva IMPLICINÍ_BARVA = Barva.ŠEDÁ;



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    /** Pozice, na kterou bude umístěno první pole okruhu. */
    private final Pozice počPozice;

    /** Barva budované cesty. */
    private final Barva barva;



//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================

    /** Počáteční pole okruhu. Je-li okruh uzavřen, je shodné s koncovým. */
    private PoleCesty první;

    /** Koncové pole okruhu. Je-li okruh uzavřen, je shodné s počátečním. */
    private PoleCesty poslední;
//%A+ >142

    /** Stavv, v němž se stavitel právě nachází a který ovlivňuje,
     * jaké příkazy je ochoten akceptovat. */
    StavStavitele stav = PŘIPRAVENÝ;
//%A-



//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří stavitele, který bude od zadané výchozí pozice
     * stavět okruh implicitní barvy.
     *
     * @param počPozice Pozice počátečního pole
     */
    public StavitelOkruhů(Pozice počPozice)
    {
        this(počPozice, IMPLICINÍ_BARVA);
    }


    /***************************************************************************
     * Vytvoří stavitele, který bude od zadané výchozí pozice
     * stavět okruh zadané barvy.
     *
     * @param počPozice Pozice počátečního bloku
     * @param barva     Barva cesty
     */
    public StavitelOkruhů(Pozice počPozice, Barva barva)
    {
        this.počPozice = počPozice;
        this.barva     = barva;
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================

    /***************************************************************************
     * Vrátí právě vytvořený okruh.
     *
     * @return Vytvořený okruh
     */
    public Okruh getOkruh()
    {
//%A+ >142
        if (stav != UKONČENÝ) {
            throw new RuntimeException(
                "\nTvorba okruhu ještě není ukončena - je ve stavu: " + stav);
        }
        stav = PŘIPRAVENÝ;
//%A-
        return new Okruh(první);
    }



//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

    /***************************************************************************
     * Přidá k okruhu další blok cesty, který bude průjezdný zadaným směrem.
     *
     * @param směr Směr průjezdnosti přidávaného bloku
     */
    public void zahajNa(Směr8 směr)
    {
//%A+ >142
        if (stav != PŘIPRAVENÝ) {
            throw new RuntimeException(
               "\nTvorbu okruhu nelze zahájit - stavitel je ve stavu: " + stav);
        }
        stav = BUDUJÍCÍ;
//%A-
        poslední = new PoleCesty(počPozice, SP.getKrok(), směr, barva);
//%I+ <141
//        SP.přidej(poslední);
//%I-
        první = poslední;
    }


    /***************************************************************************
     * Přidá k okruhu další blok cesty, který bude průjezdný zadaným směrem.
     *
     * @param směr Směr průjezdnosti přidávaného bloku
     */
    public void pokračujNa(Směr8 směr)
    {
//%A+ >142
        if (stav != BUDUJÍCÍ) {
            throw new RuntimeException(
               "\nV tvorbě okruhu nelze pokračovat - stavitel je ve stavu: " +
               stav);
        }
//%A-
        poslední = new PoleCesty(poslední, směr);
//%I+ <141
//        SP.přidej(poslední);
//%I-
    }


    /***************************************************************************
     * Přidá k okruhu závěrečný blok průjezdný zadaným směrem.
     * Tento blok napojí na počáteční blok celé sady, čímž uzavře okruh.
     *
     * @param směr Směr průjezdnosti přidávaného bloku
     */
    public void uzavřiNa(Směr8 směr)
    {
//%A+ >142
        if (stav != BUDUJÍCÍ) {
            throw new RuntimeException(
               "\nTvorbu okruhu nelze ukončit - stavitel je ve stavu: " + stav);
        }
        stav = UKONČENÝ;
//%A-
        poslední = new PoleCesty(poslední, směr, první);
//%I+ <141
//        SP.přidej(poslední);
//%I-
    }


    /***************************************************************************
     * Vrací textovou reprezentaci (podpis) dané instance
     * používanou především k ladicím účelům.
     *
     * @return Požadovaná textová reprezentace
     */
    @Override
    public String toString()
    {
        return "StavitelCest_(počátek=" + počPozice + ", barva=" + barva +
               ", první=" + první + ", poslední=" + poslední + ")";
    }



//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        StavitelOkruhů inst = new StavitelOkruhů();
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }
}

//%%-  ----- Začátek ignorovaného závěrečného textu -----
////////////////////////////////////////////////////////////////////////////////
//== TESTY A METODA MAIN =======================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        System.exit(0);
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }
}
